import copy


# 自定义异常
class ParamsTypeError(Exception):
    pass


# 给定以下列表, 通过匿名函数和常规函数根据键age来排序
classes = [
    {"name": "abyss", "age": 25, "grade": "A"},
    {"name": "kin", "age": 23, "grade": "B"},
    {"name": "tian", "age": 24, "grade": "B"},
    {"name": "hun", "age": 26, "grade": "A"},
    {"name": "exe", "age": 21, "grade": "A"}
]


# 常规函数排序
def my_sort(x):
    return x['age']


# 通过map函数将上述同学的age+1
def my_map():
    # 匿名函数实现   返回 map object   但是lambda实现不了
    # classes_map = map(lambda x: x['age'] + 1, classes)
    # print(list(classes_map))
    # 普通函数实现
    classes_map = map(foo_map, classes)
    print(f'map普通函数实现结果：{list(classes_map)}')
    print(list(classes))
    return classes_map


# 常规函数map
def foo_map(x):
    x['age'] += 1
    return x


# 通过filter函数过滤掉上述同学中grade是A的同学
def my_filter():
    classes_filter = filter(lambda x: x['grade'] != 'A', classes)
    # 普通函数实现
    # classes_filter = filter(foo_filter, classes)
    return classes_filter


# 常规函数filter
def foo_filter(x):
    return x['grade'] != 'A'


# 用递归的方式实现斐波那契数列   tag: 日志标志，想看看递归的两个函数怎么执行的
def fib_recursion(n, tag):
    try:
        format_n = int(n)
    except Exception as e:
        raise ParamsTypeError('报错了兄弟，你输入的咱不能转换为int啊：{}'.format(e.args))
    else:
        print(f'{format_n}这个参数没问题~{tag}')
        if format_n < 0:
            print('请输入>=0的正整数哦~')
            return -1
        elif format_n <= 1:
            print('format_n <= 1 进来了')
            return format_n
        return fib_recursion(int(n) - 1, '前') + fib_recursion(int(n) - 2, '后')
    finally:
        pass


if __name__ == '__main__':
    # 常规函数排序
    normal_classes = copy.deepcopy(classes)
    normal_classes.sort(key=my_sort)
    print(f'常规函数排序：{normal_classes}')

    # 匿名函数（lambda）排序
    classes.sort(key=lambda x: x['age'])
    print(f'匿名函数排序：{classes}')

    # 通过map函数将上述同学的age + 1
    res_map = my_map()
    print(f'map函数：{list(res_map)}')

    # filter函数过滤
    res_filter = my_filter()
    print(f'filter函数：{list(res_filter)}')

    # 递归调用
    n_recursion = input('请输入你要计算的斐波那契数列的项数n（recursion循环计算）:')
    result = fib_recursion(n_recursion, '递归开始')
    if result != -1:
        print(f'{n_recursion}的斐波那契数列结果为(recursion递归)：{result}')
    else:
        print('请输入>=0的正整数哦~')
